package com.evon.yardmanagement.ui.action.transaction;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.struts2.interceptor.ApplicationAware;

import com.evon.yardmanagement.dao.CarDAO;
import com.evon.yardmanagement.model.Car;
import com.evon.yardmanagement.model.KeyBox;
import com.evon.yardmanagement.model.Member;
import com.evon.yardmanagement.model.Oem;
import com.evon.yardmanagement.model.ParkingSlot;
import com.evon.yardmanagement.model.Section;
import com.evon.yardmanagement.service.CarManagementService;
import com.evon.yardmanagement.service.KeyBoxManagementService;
import com.evon.yardmanagement.service.MemberService;
import com.evon.yardmanagement.service.OEMService;
import com.evon.yardmanagement.transformer.transaction.CarEntryTransformer;
import com.evon.yardmanagement.ui.dto.KeyBoxDTO;
import com.evon.yardmanagement.ui.dto.MemberDTO;
import com.evon.yardmanagement.ui.dto.OemDTO;
import com.evon.yardmanagement.ui.dto.ParkingSlotDTO;
import com.evon.yardmanagement.ui.dto.YardDTO;
import com.evon.yardmanagement.ui.dto.transaction.CarDTO;
import com.opensymphony.xwork2.ActionSupport;

public class CarEntryAction extends ActionSupport implements ApplicationAware {

	private CarManagementService service = new CarManagementService();

	private Map<String, Object> globalData;

	public CarDTO carDTO;

	private List<Oem> listOem = new ArrayList<Oem>();
	private int selectedOemId;

	private List<YardDTO> listYard = new ArrayList<YardDTO>();
	private int selectedYardId;

	private List<ParkingSlot> listParkingSlot = new ArrayList<ParkingSlot>();
	private int selectedParkingId;

	private List<MemberDTO> availableMembers = new ArrayList<MemberDTO>();
	private int selectedMemberId;

	private List<KeyBox> availableKeyBox = new ArrayList<KeyBox>();
	private int selectedKeyBoxId;

	private List<Section> listSection = new ArrayList<Section>();
	private int selectedSectionId;

	public CarEntryAction() {
		this.carDTO = new CarDTO();

	}

	public int getSelectedOemId() {
		return selectedOemId;
	}

	public void setSelectedOemId(int selectedOemId) {
		this.selectedOemId = selectedOemId;
	}

	public int getSelectedMemberId() {
		return selectedMemberId;
	}

	public void setSelectedMemberId(int selectedMemberId) {
		this.selectedMemberId = selectedMemberId;
	}

	public int getSelectedYardId() {
		return selectedYardId;
	}

	public void setSelectedYardId(int selectedYardId) {
		this.selectedYardId = selectedYardId;
	}

	public String getYardName() {
		return carDTO.getYardName();
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public String execute() throws Exception {
		// Reassign the previously selected value.
		listYard = (List<YardDTO>) globalData.get("Yards");
		listOem = (List<Oem>) globalData.get("Oems");
		listSection = (List<Section>) globalData.get("Sections");
		availableMembers = (List<MemberDTO>) globalData.get("Drivers");
		availableKeyBox = (List<KeyBox>) globalData.get("KeyBoxes");
		// Get the available parking slot for the yard in priority order.
		listParkingSlot = (List<ParkingSlot>) globalData.get("ParkingSlots");

		System.err.println("Selected YARD" + selectedYardId);
		setSelectedFields();
		if (!isInputValid()) {
			return INPUT;
		}

		// print the DTO.
		Car newCarEntry = CarEntryTransformer.transform(carDTO);
		// TODO : Move it to Service, don't expose DAO here.
		new CarDAO().saveOrUpdate(newCarEntry);
		// mark the parking slot as busy
		service.markSlotOccuppied(selectedParkingId, selectedMemberId,
				selectedKeyBoxId);
		addActionMessage("Parking Request has been set for Car Chasis Number - "
				+ carDTO.getCarChasisNumber());
		// Empty the form for next car entry
		emptyFields();
		return SUCCESS;
	}

	public void emptyFields() {
		carDTO = new CarDTO();
		selectedKeyBoxId = 0;
		selectedMemberId = 0;
		selectedOemId = 0;
		selectedParkingId = 0;
		selectedSectionId = 0;

		// Repopulate the member and key box as the currently selected member
		// might be occupied by now.
		if (selectedYardId > 0) {
			availableMembers = new MemberService()
					.getUnOccupiedMembersOfYard(selectedYardId);

			globalData.put("Drivers", availableMembers);

			availableKeyBox = new KeyBoxManagementService()
					.getAvailableKeyForForYard(selectedYardId);
			globalData.put("KeyBoxes", availableKeyBox);
		}

	}
	
	public String cancelAction(){
		// Reassign the previously selected value.
		listYard = (List<YardDTO>) globalData.get("Yards");
		listOem = (List<Oem>) globalData.get("Oems");
		listSection = (List<Section>) globalData.get("Sections");
		
		emptyFields();
		
		return SUCCESS;
	}

	/**
	 * Validate the input and return true , if all fields populated, else return
	 * false.
	 * 
	 * @return
	 */
	private boolean isInputValid() {
		if (carDTO.getCarChasisNumber() == null
				|| carDTO.getCarChasisNumber().trim().length() == 0) {
			addFieldError("carDTO.carChasisNumber",
					"Please enter Car chasis number");
			return false;
		}

		if (carDTO.getCarModel() == null
				|| carDTO.getCarModel().trim().length() == 0) {
			addFieldError("carDTO.carModel", "Please enter Car Model");
			return false;
		}
		if (carDTO.getCarNumber() == null
				|| carDTO.getCarNumber().trim().length() == 0) {
			addFieldError("carDTO.carNumber", "Please enter Car Number");
			return false;
		}

		if (carDTO.getCarColor() == null
				|| carDTO.getCarColor().trim().length() == 0) {
			addFieldError("carDTO.carColor", "Please enter Car Color");
			return false;
		}
		if (carDTO.getCarVerient() == null
				|| carDTO.getCarVerient().trim().length() == 0) {
			addFieldError("carDTO.carVarient", "Please enter Car Varient");
			return false;
		}
		if (carDTO.getKeyNumber() <= 0) {
			addFieldError("carDTO.keyNumber", "Please enter Car Key Number");
			return false;
		}

		if (carDTO.getParkingSlot().getId() <= 0) {
			addFieldError("carDTO.ParkingSlot", "Please select parking slot");
			return false;
		}

		if (carDTO.getMember().getId() <= 0) {
			addFieldError("carDTO.member", "Please select a driver");
			return false;
		}

		return true;
	}

	private void setSelectedFields() {
		ParkingSlotDTO slotDTO = carDTO.getParkingSlot();
		if (slotDTO == null) {
			slotDTO = new ParkingSlotDTO();
		}
		slotDTO.setId(selectedParkingId);
		carDTO.setParkingSlot(slotDTO);

		MemberDTO memberDTO = carDTO.getMember();
		if (memberDTO == null) {
			memberDTO = new MemberDTO();
		}
		memberDTO.setId(selectedMemberId);
		carDTO.setMember(memberDTO);

		KeyBoxDTO keyBoxDTO = carDTO.getKeyBox();
		if (keyBoxDTO == null) {
			keyBoxDTO = new KeyBoxDTO();
		}
		keyBoxDTO.setKeyBoxId(selectedKeyBoxId);
		carDTO.setKeyBox(keyBoxDTO);

		carDTO.setParkingSlot(slotDTO);

		if (carDTO.getCarManufacturer() == null) {
			carDTO.setCarManufacturer(new OemDTO());
		}
		carDTO.getCarManufacturer().setOemId(selectedOemId);

		carDTO.setYardId(selectedYardId);

	}

	public String populateOEM() {
		listOem = new OEMService().getOemForYard(selectedYardId);
		listYard = (List<YardDTO>) globalData.get("Yards");
		globalData.put("Oems", listOem);

		availableMembers = new MemberService()
				.getUnOccupiedMembersOfYard(selectedYardId);
		globalData.put("Drivers", availableMembers);

		listSection = CarManagementService.getAvailableSections(selectedYardId);
		globalData.put("Sections", listSection);

		availableKeyBox = new KeyBoxManagementService()
				.getAvailableKeyForForYard(selectedYardId);
		globalData.put("KeyBoxes", availableKeyBox);

		return SUCCESS;
	}

	public String init() throws Exception {
		carDTO = new CarDTO();
		listYard = CarManagementService.getAvailableYards();

		// listYard = new YardManagementService().getAllYards();
		globalData.put("Yards", listYard);
		// listYard = YardTransformer.transform(listYards);
		return SUCCESS;
	}

	public String allocateParking() {
		// Remember the earier selection
		listYard = (List<YardDTO>) globalData.get("Yards");
		listOem = (List<Oem>) globalData.get("Oems");
		listSection = (List<Section>) globalData.get("Sections");
		availableMembers = (List<MemberDTO>) globalData.get("Drivers");
		availableKeyBox = (List<KeyBox>) globalData.get("KeyBoxes");
		// Get the available parking slot for the yard in priority order.
		listParkingSlot = service.allocateParking(selectedSectionId);
		globalData.put("ParkingSlots", listParkingSlot);
		// carDTO.parkingSlot =BaseTransformer.transform(slot
		// ,carDTO.parkingSlot);
		// carDTO.parkingSlot.setSlotName(slot.getName());
		// carDTO.parkingSlot.setSlotNumber(slot.getNumber());
		// carDTO.setSectionName(slot.getSection().getName());
		// carDTO.setSectionId(slot.getSection().getId());

		// availableKeyBox = new KeyBoxManagementService().
		// Get the drivers for that yard

		return SUCCESS;
	}

	public String showSelectedSection() {
		// Get the earlier selection
		listYard = (List<YardDTO>) globalData.get("Yards");
		listOem = (List<Oem>) globalData.get("Oems");
		listParkingSlot = (List<ParkingSlot>) globalData.get("ParkingSlots");
		availableMembers = (List<MemberDTO>) globalData.get("Drivers");
		availableKeyBox = (List<KeyBox>) globalData.get("KeyBoxes");

		if (selectedParkingId > 0) {
			for (ParkingSlot slot : listParkingSlot) {
				if (slot.getId() == selectedParkingId) {
					carDTO.setSectionName(slot.getSection().getName());
					carDTO.setSectionId(slot.getSection().getId());
					break;
				}
			}
			// set the section details

		}
		return SUCCESS;
	}

	public List<MemberDTO> getAvailableMembers() {
		return availableMembers;
	}

	public void setAvailableMembers(List<MemberDTO> availableMembers) {
		this.availableMembers = availableMembers;
	}

	public void setApplication(Map<String, Object> application) {
		this.globalData = application;
	}

	public int getSelectedParkingId() {
		return selectedParkingId;
	}

	public void setSelectedParkingId(int selectedParkingId) {
		this.selectedParkingId = selectedParkingId;
	}

	public List<Oem> getListOem() {
		return listOem;
	}

	public void setListOem(List<Oem> listOem) {
		this.listOem = listOem;
	}

	public List<YardDTO> getListYard() {
		return listYard;
	}

	public void setListYard(List<YardDTO> listYard) {
		this.listYard = listYard;
	}

	public List<ParkingSlot> getListParkingSlot() {
		return listParkingSlot;
	}

	public void setListParkingSlot(List<ParkingSlot> listParkingSlot) {
		this.listParkingSlot = listParkingSlot;
	}

	public List<KeyBox> getAvailableKeyBox() {
		return availableKeyBox;
	}

	public void setAvailableKeyBox(List<KeyBox> availableKeyBox) {
		this.availableKeyBox = availableKeyBox;
	}

	public int getSelectedKeyBoxId() {
		return selectedKeyBoxId;
	}

	public void setSelectedKeyBoxId(int selectedKeyBoxId) {
		this.selectedKeyBoxId = selectedKeyBoxId;
	}

	public List<Section> getListSection() {
		return listSection;
	}

	public void setListSection(List<Section> listSection) {
		this.listSection = listSection;
	}

	public int getSelectedSectionId() {
		return selectedSectionId;
	}

	public void setSelectedSectionId(int selectedSectionId) {
		this.selectedSectionId = selectedSectionId;
	}

}
